package edu.ccut.saturn.component;

import java.util.LinkedList;
import java.util.List;

/**
 * 记录验证的结果，维护了验证错误信息的列表。
 * 
 * @author 谷钰
 * @author 温建
 * 
 * @version 1.0 2008.9.03
 * 
 * @see ValidateError
 * 
 */
public class ValidateResult {

	private List<ValidateError> errors;

	private static final String KEY_NODE_VALUE = "value";

	private static final String KEY_NODE_KEY = "key";

	private static final String KEY_NODE_MAP = "map";

	private static final String KEY_NODE_LIST = "list";

	private static final String ERROR_MESSAGE = "__ERROR_MESSAGE__";

	public ValidateResult() {
		this.errors = new LinkedList<ValidateError>();
	}

	/**
	 * 根据验证结果判断验证操作是否成功
	 * 
	 * @return
	 */
	public boolean isSuccessful() {
		return this.errors.isEmpty();
	}

	/**
	 * 为验证结果添加验证错误信息
	 * 
	 * @param error
	 */
	public void addValidateError(ValidateError error) {
		this.errors.add(error);
	}

	/**
	 * 为验证结果添加验证错误信息
	 * 
	 * @param errorMessage
	 * @param exception
	 * @param valueObject
	 */
	public void addValidateError(String errorMessage, Throwable exception,
			Object valueObject) {

		this.errors
				.add(new ValidateError(errorMessage, exception, valueObject));
	}

	/**
	 * 为验证结果添加验证错误信息
	 * 
	 * @param errorMessage
	 * @param valueObject
	 */
	public void addValidateError(String errorMessage, Object valueObject) {
		this.errors.add(new ValidateError(errorMessage, null, valueObject));
	}

	/**
	 * 获得验证结果列表
	 * 
	 * @return
	 */
	public List<ValidateError> getErrors() {
		return this.errors;
	}

	/**
	 * 获得验证结果的字符串表示
	 */
	public String toString() {
		StringBuffer message = new StringBuffer();

		for (ValidateError error : this.errors) {
			message.append(error).append("\n");
		}

		return message.toString();
	}

	/**
	 * 获得验证结果的xml格式数据的字符串
	 * 数据格式为
	 * <list key="__ERROR_MESSAGE__">
	 * <map key="">----map结点是对一个ValidateError实例的描述
	 * <value key="validateValue"></value>----描述了验证错误中记录的验证对象
	 * <value key="message"></value>----描述了验证错误中记录的验证错误信息
	 * <value key="exception"></value>----描述了验证错误中记录的异常信息
	 * </map>
	 * </list>
	 * 
	 * @return
	 */
	public String toXml() {

		if (this.errors != null && this.errors.size() > 0) {
			StringBuffer stringBuffer = new StringBuffer();
			stringBuffer.append("<");
			stringBuffer.append(KEY_NODE_LIST);
			stringBuffer.append(" ");
			stringBuffer.append(KEY_NODE_KEY);
			stringBuffer.append("=\"");
			stringBuffer.append(ERROR_MESSAGE);
			stringBuffer.append("\">");
			int i = 0;

			for (ValidateError error : this.errors) {
				stringBuffer.append("<");
				stringBuffer.append(KEY_NODE_MAP);
				stringBuffer.append(" ");
				stringBuffer.append(KEY_NODE_KEY);
				stringBuffer.append("=\"" + (i++) + "\">");
				getValueNode(stringBuffer, error);
				stringBuffer.append("</");
				stringBuffer.append(KEY_NODE_MAP);
				stringBuffer.append(">");
			}
			stringBuffer.append("</");
			stringBuffer.append(KEY_NODE_LIST);
			stringBuffer.append(">");

			return stringBuffer.toString();
		}
		return null;
	}

	private void getValueNode(StringBuffer stringBuffer, ValidateError error) {
		getValueNode(stringBuffer, (String) error.getValidateValue(),
				"validateValue");

		getValueNode(stringBuffer, error.getErrorMessage(), "message");
		String exception = null;

		if (error.getException() != null) {
			exception = error.getException().getMessage();
		}
		getValueNode(stringBuffer, exception, "exception");
	}

	private void getValueNode(StringBuffer stringBuffer, String error,
			String key) {

		stringBuffer.append("<");
		stringBuffer.append(KEY_NODE_VALUE);
		stringBuffer.append(" ");
		stringBuffer.append(KEY_NODE_KEY);
		stringBuffer.append("=\"");

		stringBuffer.append(key);
		stringBuffer.append("\">");

		if (error != null) {
			stringBuffer.append(error);
		}
		stringBuffer.append("</");
		stringBuffer.append(KEY_NODE_VALUE);
		stringBuffer.append(">");
	}
}
